package com.open4cn.simulator.parser.datacolor.dc600;

import com.open4cn.simulator.answer.LogInstructionAction;
import com.open4cn.simulator.answer.datacolor.GreenboardAction;
import com.open4cn.simulator.answer.datacolor.UV0Greenboard600Answer;
import com.open4cn.simulator.answer.datacolor.UV0Measure600Answer;
import com.open4cn.simulator.answer.datacolor.UV100Greenboard600Answer;
import com.open4cn.simulator.answer.datacolor.UV100Measure600Answer;
import com.open4cn.simulator.answer.datacolor.Whiteboard2Answer;
import com.open4cn.simulator.answer.datacolor.Whiteboard4Answer;
import com.open4cn.simulator.answer.datacolor.Whiteboard5Answer;
import com.open4cn.simulator.answer.datacolor.Whiteboard600Action;
import com.open4cn.simulator.answer.datacolor.Whiteboard6Answer;
import com.open4cn.simulator.core.answer.AbstractAnswer;
import com.open4cn.simulator.core.answer.AnswerResponse;
import com.open4cn.simulator.core.ext.DataColorStatus;
import com.open4cn.simulator.core.parser.IInstructionParser;
import com.open4cn.simulator.core.parser.InstructionParserChain;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Arrays;
import java.util.List;

/**
 * @author yinxiaopeng
 * @version 1.0.0
 * @company 致景科技
 * @department 飞梭BU/研发
 * @description *M1@000EE:
 * *M1@100EF:
 * *M1@200F0:
 * ...
 * *M2@0100150:
 * *M2@1100151:
 * *M2@2100152:
 * ...
 * @Email yinxiaopeng@zj.tech
 * @date 2022-05-03 17:42
 */
public class M$$Pattern implements IInstructionParser {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    private static final String COMMAND = "*M$@";

    private Whiteboard2Answer whiteboard2Answer = new Whiteboard2Answer();
    private Whiteboard4Answer whiteboard4Answer = new Whiteboard4Answer();
    private Whiteboard5Answer whiteboard5Answer = new Whiteboard5Answer();
    private Whiteboard6Answer whiteboard6Answer = new Whiteboard6Answer();
    private UV100Greenboard600Answer UV100Greenboard600Answer = new UV100Greenboard600Answer();
    private UV0Greenboard600Answer UV0Greenboard600Answer = new UV0Greenboard600Answer();
    private UV100Measure600Answer UV100Measure600Answer = new UV100Measure600Answer();
    private UV0Measure600Answer UV0Measure600Answer = new UV0Measure600Answer();

    private DataColorStatus dataColorStatus;

    public M$$Pattern(DataColorStatus dataColorStatus) {
        this.dataColorStatus = dataColorStatus;
        init();
    }

    private void init() {
        whiteboard2Answer.setActions(Arrays.asList(
                new LogInstructionAction(),
                new Whiteboard600Action()
        ));
        whiteboard4Answer.setActions(Arrays.asList(
                new LogInstructionAction(),
                new Whiteboard600Action()
        ));
        whiteboard5Answer.setActions(Arrays.asList(
                new LogInstructionAction(),
                new Whiteboard600Action()
        ));
        whiteboard6Answer.setActions(Arrays.asList(
                new LogInstructionAction(),
                new Whiteboard600Action()
        ));
        UV100Greenboard600Answer.setActions(Arrays.asList(
                new LogInstructionAction(),
                new GreenboardAction()
        ));
        UV0Greenboard600Answer.setActions(Arrays.asList(
                new LogInstructionAction(),
                new GreenboardAction()
        ));
        UV100Measure600Answer.setActions(Arrays.asList(
                new LogInstructionAction()
        ));
        UV0Measure600Answer.setActions(Arrays.asList(
                new LogInstructionAction()
        ));
    }

    @Override
    public Object parse(Object msg, InstructionParserChain chain) {
        String instruction = (String) msg;
        if (!match(instruction)) {
            return chain.filter(msg);
        }

        AnswerResponse response = null;
        if (!dataColorStatus.inCorrecting()) {
            if (DataColorStatus.UVEnum.UV100.equals(dataColorStatus.getCurrentUV())) {
                response = UV100Measure600Answer.answer(dataColorStatus, instruction);
            } else {
                response = UV0Measure600Answer.answer(dataColorStatus, instruction);
            }
        } else {
            if (DataColorStatus.CorrectionStageEnum.WHITE_BOARD.equals(dataColorStatus.getCurrentCorrectionStage())) {
                if (dataColorStatus.whiteboardFrequency() == 3) {
                    response = whiteboard4Answer.answer(dataColorStatus, instruction);
                } else if (dataColorStatus.whiteboardFrequency() == 4) {
                    response = whiteboard5Answer.answer(dataColorStatus, instruction);
                } else if (dataColorStatus.whiteboardFrequency() == 5) {
                    response = whiteboard6Answer.answer(dataColorStatus, instruction);
                } else {
                    response = whiteboard2Answer.answer(dataColorStatus, instruction);
                }
            } else {
                if (DataColorStatus.UVEnum.UV100.equals(dataColorStatus.getCurrentUV())) {
                    response = UV100Greenboard600Answer.answer(dataColorStatus, instruction);
                } else {
                    response = UV0Greenboard600Answer.answer(dataColorStatus, instruction);
                }
            }
        }
        return response.getData();
    }


    /**
     * 匹配
     *
     * @param instruction
     * @return
     */
    private boolean match(String instruction) {
        if (null == instruction) {
            return false;
        }

        if (COMMAND.length() > instruction.length()) {
            return false;
        }

        for (int i = 0, len = COMMAND.length(); i < len; i++) {
            String charAt = String.valueOf(COMMAND.charAt(i));
            if ("$".equals(charAt)) {
                continue;
            }
            if ("@".equals(charAt)) {
                break;
            }
            if (COMMAND.charAt(i) != instruction.charAt(i)) {
                return false;
            }
        }
        return true;
    }


    @Override
    public List<AbstractAnswer> getAnswers() {
        return Arrays.asList(
                whiteboard2Answer, whiteboard4Answer, whiteboard5Answer, whiteboard6Answer,
                UV100Greenboard600Answer, UV0Greenboard600Answer, UV100Measure600Answer, UV0Measure600Answer
        );
    }
}
